home *** CD-ROM | disk | FTP | other *** search
- Subject: v13i059: Hardware-independant modem routines
- Newsgroups: comp.sources.unix
- Sender: sources
- Approved: rsalz@uunet.UU.NET
-
- Submitted-by: The Beach Bum <ulysses!ihnp4!killer!jfh@seismo.CSS.GOV>
- Posting-number: Volume 13, Issue 59
- Archive-name: modemcap
-
- This is a modem-independant dial(3) package, with a termcap-style
- description file. No manual page -- refer to the relevant (SystemV)
- manuals.
-
- #! /bin/sh
- # This is a shell archive, meaning:
- # 1. Remove everything above the #! /bin/sh line.
- # 2. Save the resulting text in a file.
- # 3. Execute the file with /bin/sh (not csh) to create:
- # README
- # makefile
- # modemcap
- # modemtype
- # modemcap.h
- # mgetent.c
- # mgetstr.c
- # mgetflag.c
- # mgetnum.c
- # mdial.c
- # merror.c
- # initmodem.c
- # hangup.c
- # dial.c
- # call.c
- # This archive created: Mon Nov 2 13:32:08 1987
- export PATH; PATH=/bin:/usr/bin:$PATH
- if test -f 'README'
- then
- echo shar: "will not over-write existing file 'README'"
- else
- cat << \SHAR_EOF > 'README'
- This package is a modem independent dial(3) package. It provides a device
- independent method for dialing and manipulating modems. The format of the
- description file is the ever present ;-) termcaps format. You may want to
- read the modemcap file to see just what capabilities are present.
-
- This is Release 1.1 of this software. Please bear in mind that I haven't
- released this to the public before this release.
-
- --< Start of the legal conditions of this software >--
-
- This software is copyright 1987 John F. Haugh II, all rights reserved.
- Use, duplication and disclosure subject to the terms and conditions of
- the license agreement below. This notice is intended to have legal
- significance, and not to be taken lightly. If you have any questions,
- please contact the author at the address below. This copyright covers
- the entire software distribution it is enclosed with. Removing this
- copyright is a violation of federal copyright law. Please consult an
- attorney if you have any questions regarding the legal ramifications of
- this agreement.
-
- This software is licensed subject to the following terms and conditions.
- In order that this product may expand into the universe to fill the current
- (void) in this area, it is my intention that this software be widely
- distributed, and maintained in a consistent fashion. To this end, you
- are authorized to redistribute this software in either source or binary
- format, provided that, this agreement is retained as part of the release,
- no direct profit is realized from the sale or transfer of this software,
- and that credit is given the author for this work. To facilitate this
- package coming into acceptance, you must provide library versions of this
- software and any documentation included with this package when distributing
- binary versions embedded in your products. Paying royalties would be
- nice and you won't do it anyway, so don't even pretend to be nice people
- unless you really want me to stay on top of this thing. Author retains
- all rights to derived works, and as a condition to your making modifications
- to the source code, you are required by this agreement to provide detailed
- notes concerning the actual modifications and the motivation behind the
- modification itself. Making the documentation look better is a nice idea
- also. And since I'm very lazy, please send me your documentation. You
- don't have to, but standardized documentation is a Good Thing.
-
- The author provides this software without warrantee. The user accepts by
- use all responsibility for the performance (or lack thereof ;-) of this
- software, including loss of profits, reputation, or job.
-
- --< End of the legal stuff, now for the documentation. >--
-
- call.c - a test program. do a `make all' to create the library and compile
- the call program. read all the documentation before trying it out.
-
- dial(3L) - a version of the standard dial(3) command which should be fairly
- compatible with the one in your manual ... has both dial() and undial()
- routines. see your manpage for more details.
-
- hangup.c/hangup(3L) - a routine that attempts to absolutely hangup a modem.
- it uses the modem capabilities database to figure out the best way to
- hangup a modem. it supports both hangup on DTR and hangup on command.
-
- initmodem.c/initmodem(3L) - this routine takes a character pointer to a
- modem name as it appears in the database and a file descriptor from a
- open() call, and loads the database information. after the database is
- loaded, the modem is placed in the command mode. beware, initmodem()
- may make an alarm(2) call if the InitializationDelay requirement is present.
-
- mdial.c/mdial(3L) - this routine builds a dial command string to give
- to the dialer. this is the weakest routine in the package, because i don't
- have that many different modems around here, and hayes is pretty damned
- common, so i don't see many others. the first argument is a character string
- telephone number, digits only, or if you understand your modem (boo on me)
- you can put in pause commands. the second argument is a file descriptor
- from an open() call. this routine _will_ be the first to get fixed.
-
- merror.c/merror(3L) - this routine is a modemcap replacement for perror.
- an `int merrno' variable is maintained by the routines. after an error
- return, you can call merror with a character pointer just like perror(3)
- and have a message printed on your standard error output.
-
- mgetent.c/mgetent(3L) - this is a low level routine you shouldn't be
- calling anyway. it works like tgetent(3), only different. mostly, it
- doesn't have the neat things. the first argument is a pointer to a
- character buffer where the entry will be placed. the second argument
- is a pointer to the modem name.
-
- mgetflag.c/mgetflag(3L) - just like tgetflag. this is a low level
- routine you might just want to use. in particular, `if (mgetflag ("hc"))'
- tests for modem hanging up on DTR being negated. `if (HC)' does the
- same thing after mgetent() ...
-
- mgetnum.c/mgetnum(3L) - just like tgetnum. don't see much use for using
- it.
-
- mgetstr.c/mgetstr(3L) - just like tgetstr, except it has a few quirks.
- octal escapes are all three digits. the format '^c' where 'c' is some
- character, only works with upper case letters. correctly at least.
- ain't no way to get a null into the string, no how.
-
- /etc/modemcap - a modem capabilities database. read the file for more
- details.
-
- /etc/modemtype - a modem/port mapping table. look at the example file.
-
- you will need to make entries for your devices in the L-devices file.
- the speed listed must be a legal speed according to the modemcap file.
- any compilation errors or warnings should be brought to my attention. i
- didn't get any the last time i compiled all this stuff.
-
- the source is well enough (i'm lieing) documented for anyone to fix.
- please don't add your local improvement. if you insist, make the mods
- and send me context diffs. i'll tell you what i think about the change.
- remember, according to the license you must let me in on what you are
- doing. this is in everyones best interest.
-
- --< End of the documentation, now for my personal philosophical b.s. >--
-
- It is not my intention to limit the use of this software or your profits,
- except where such use is inconsistent with the spirit of humanity, whatever
- the hell that means. I don't care how much money you make selling your
- new terminal program, just don't go jacking the price up because you
- have added this thing. I will only work on this package if I get feedback
- and I have some motivation, other than being a nice guy. I think I've been
- nice enough by putting this thing out there. If what you want makes sense
- in a real way, I will probably include your suggestions, and if you are
- polite, I might just give you credit ;-) So don't be a jerk and pretend
- that anyone actually works for free. I have a car note just like you.
-
- By way of this license and the legal mumbo-jumbo, I hope to keep people
- from ripping me off, and totally trashing and perverting the integrity
- of the code. Please, don't construe this agreement to be limiting in
- a negative way. I hope to provide just enough limits to keep the code
- consistent and portable across all machine environments, and hopefully,
- you will use this thing enough that it becomes better and more useful
- and fills the need for such a thing. Who knows, we both might just make
- some money off of this thing.
-
- --
- John F. Haugh II QUOTE: "The important thing is to not stop
- 7825 McCallum Blvd. questioning" -- Albert Einstein
- Apt. 510 TELCO: (214) 250-3311
- Dallas, TX 75252 UUCP: { backbone } !ihnp4!killer!jfh
- SHAR_EOF
- fi
- if test -f 'makefile'
- then
- echo shar: "will not over-write existing file 'makefile'"
- else
- cat << \SHAR_EOF > 'makefile'
- # Your library directory.
- LIBDIR=/usr/lib
- # Your local command directory.
- LBIN=/usr/local/bin
- OSFLAG=-DUNIX_S5 # For System V machines.
- # OSFLAG=-DUNIX_V7 # For Version 7 machines.
- # For those poor people who need ranlib
- # RANLIB=ranlib $(LIBDIR)/libmodemcap.a
- # Standard Bourne shell.
- SHELL=/bin/sh
-
- CFLAGS=-O
- LDFLAGS=-s
-
- OFILES=mgetent.o mgetstr.o mgetflag.o mgetnum.o mdial.o merror.o \
- initmodem.o hangup.o dial.o
-
- CFILES=mgetent.c mgetstr.c mgetflag.c mgetnum.c mdial.c merror.c \
- initmodem.c hangup.c dial.c
-
- LFILES=libmodemcap.a(mgetent.o)\
- libmodemcap.a(mgetstr.o)\
- libmodemcap.a(mgetflag.o)\
- libmodemcap.a(mgetnum.o)\
- libmodemcap.a(mdial.o)\
- libmodemcap.a(merror.o)\
- libmodemcap.a(initmodem.o)\
- libmodemcap.a(hangup.o)\
- libmodemcap.a(dial.o)
-
- all: $(LFILES)
-
- install: all call
- cp modemcap.h /usr/include
- cp modemcap /etc/modemcap
- cp modemtype /etc/modemtype
- cp libmodemcap.a $(LIBDIR)
- chmod 644 /usr/include/modemcap.h /etc/modemcap /etc/modemtype $(LIBDIR)/libmodemcap.a
- cp call $(LBIN)/call
- chmod 711 $(LBIN)/call
-
- call: call.c libmodemcap.a
- cc $(LDFLAGS) $(CFLAGS) call.c libmodemcap.a -o call
-
- initmodem.o: initmodem.c /usr/include/modemcap.h
-
- mdial.o: mdial.c /usr/include/modemcap.h
-
- hangup.o: hangup.c /usr/include/modemcap.h
-
- dial.o: dial.c /usr/include/modemcap.h
-
- shar: README $(CFILES) makefile modemcap modemtype modemcap.h call.c
- shar README makefile modemcap modemtype modemcap.h $(CFILES) call.c > modem.shar
- SHAR_EOF
- fi
- if test -f 'modemcap'
- then
- echo shar: "will not over-write existing file 'modemcap'"
- else
- cat << \SHAR_EOF > 'modemcap'
- #
- # @(#)modemcap 1.0
- #
- # First attempt at a modem capabilities database.
- #
- # Capabilities are:
- #
- # Name Type Meaning
- #
- # as flag Numbers are in ASCII, not binary
- # at string Attention string, forces model into command mode from online mode
- # ad number Delay after AS
- # bd number Highest online baud rate
- # bl number Alternate lower baud rate
- # cs string Command start string
- # ce string Command end string (required if CS is present)
- # co string String from modem on remote connection at BD baud rate
- # cl string String from modem on remote connection at BL baud rate
- # di flag Modem has a dialer
- # ds string Start dial command string
- # de string End dial command string (required if DS is present)
- # is string Initialization string, resets modem to offline, ready to dial
- # id number Delay after IS
- # hc flag Modem hangs up when DTR drops
- # hu string Hangup command
- # tt flag Modem dials touchtone by default (or DS is set that way)
- #
- # All commands, such as DS (dial command) and HU (hang up) will be prefixed by
- # CS and ended with CE. If there is a common prefix and suffix, use this feature.
- # Otherwise, each command will have to have the entire string built in.
- #
- hy|hayes|Hayes Smartmodem 1200:\
- :as:at=+++:ad#6:bd#1200:bl#300:cs=AT:ce=\r:co=CONNECT:\
- :cl=CONNECT:di:ds=DT :de=:is=ATQ0 V1 E1\r:id#2:\
- :hc:hu=H0 V0 E0 Q1:tt:
- si|mk12|Signalman Mark XII:\
- :as:at=+++:ad#6:bd#1200:bl#300:cs=AT:ce=\r:co=CONNECT 1200:\
- :cl=CONNECT:di:ds=DT :de=:is=ATQ0 V1 E1\r:id#2:\
- :hu=H0 V0 E0 Q1:tt:
- ds|dc300|Radio Shack Direct-Connect 300 Modem:\
- :bd#300:bl#110:
- SHAR_EOF
- fi
- if test -f 'modemtype'
- then
- echo shar: "will not over-write existing file 'modemtype'"
- else
- cat << \SHAR_EOF > 'modemtype'
- hayes1200 tty38
- hayes1200 tty39
- ch1770 modem
- SHAR_EOF
- fi
- if test -f 'modemcap.h'
- then
- echo shar: "will not over-write existing file 'modemcap.h'"
- else
- cat << \SHAR_EOF > 'modemcap.h'
- /*
- * @(#)modemcap.h 1.0
- *
- * names of variables and whatnots for modemcap file
- */
-
- char AS, /* True if numbers dialed in ASCII, False for binary digits */
- DI, /* True if modem can dial numbers, False otherwise */
- HC, /* True if modem hangs up when DTR drops, False otherwise */
- TT; /* True if modem uses touchtone by default, False for pulse */
-
- char *AT, /* Enter command state when online */
- *CS, /* Command start string */
- *CE, /* Command end string - must be present if CS is */
- *DS, /* Dial command string */
- *DE, /* End of dial command string - must be present if DS is */
- *CO, /* Connection made at primary baud rate */
- *CL, /* Connection made at secondary (lower) baud rate */
- *IS, /* Initialization string - reset modem to onhook and ready */
- *HU; /* Hangup command */
-
- int AD, /* Delay after AT string before next command */
- BD, /* Highest communications baud rate */
- BL, /* Another, lower baud rate */
- ID; /* Delay time after initialization */
-
- /*
- * The dial command is the principle string that must be built.
- * The routines will build a dial command as follows:
- *
- * <CS><DS><phone-number><DE><CE>
- *
- * Note that the DE and CE strings are present ALWAYS.
- * This procedure will be used to dial phone numbers if the DI flag is true.
- * If this isn't the way to dial numbers,
- * DO NOT SET DI IN THE MODEMCAP FILE!!!
- */
-
- /*
- * The type of modem is determined by reading the file "_MODEMTYPE_". This
- * is similiar to the way curses works by reading the ttytype file.
- */
-
- #define _MODEMTYPE_ "/etc/modemtype"
-
- /*
- * a hangup command will be performed as follows:
- *
- * 1). any attention string (AT) will be sent followed by the delay (AD)
- * 2). modem should now be in command state, send hangup (HU) command
- * 3). send initialization string (IS) followed by the delay (ID)
- *
- * It is important that you determine a correct AT and HU string
- * to perform this function.
- * If the modem hangs up when DTR falls (even if there is a HU string),
- * declare the flag HC (for Hangup on Close).
- */
-
- SHAR_EOF
- fi
- if test -f 'mgetent.c'
- then
- echo shar: "will not over-write existing file 'mgetent.c'"
- else
- cat << \SHAR_EOF > 'mgetent.c'
- #include <stdio.h>
-
- char *__modemcap;
- char *MODEMCAP = "/etc/modemcap";
-
- static isent (ent, name)
- char *ent;
- char *name;
- {
- char buf[16];
- register int i;
-
- while (*ent != ':' && *ent != 0) {
- for (i = 0;*ent != ':' && *ent != '|' && *ent != 0 && i < 15;i++)
- buf[i] = *ent++;
-
- if (*ent == '|')
- ent++;
-
- buf[i] = 0;
- if (strcmp (buf, name) == 0)
- return (1);
- }
- return (0);
- }
-
- mgetent (bp, name)
- char *bp;
- char *name;
- {
- char buf[1024];
- register char *cp;
- register FILE *modemcap;
- register int i;
- char *getenv ();
-
- if ((cp = getenv ("MODEMCAP")) != NULL) {
- if (*cp != '/') {
- if (isent (cp, name)) {
- strcpy (buf, cp);
- return (1);
- }
- }
- MODEMCAP = cp;
- }
- if ((modemcap = fopen (MODEMCAP, "r")) == NULL)
- return (-1);
-
- while (fgets (buf, 512, modemcap) != NULL) {
- if (buf[0] == '#') /* skip all comment lines */
- continue;
-
- i = strlen (buf) - 1; /* find last character in line */
- buf[i] = 0; /* remove trailing newline */
- if (i == 0) /* ignore blank lines */
- continue;
-
- while (buf[(i = strlen (buf) - 1)] == '\\') { /* is last character a \\, still more */
- cp = &buf[i]; /* find last character */
- cp[0] = 0; /* nullify, end of this part */
- if (fgets (cp, 512, modemcap) == NULL) /* end of file? ... */
- break; /* ... end of entry */
-
- cp[strlen (cp) - 1] = 0; /* remove trailing newline */
- if (cp[0] == '#') { /* comment line? ... */
- cp[0] = 0; /* remove that line */
- continue; /* go get another line */
- }
- }
- if (isent (buf, name)) {
- __modemcap = bp;
- strcpy (bp, buf);
- fclose (modemcap);
- return (1);
- }
- }
- fclose (modemcap);
- return (0);
- }
- SHAR_EOF
- fi
- if test -f 'mgetstr.c'
- then
- echo shar: "will not over-write existing file 'mgetstr.c'"
- else
- cat << \SHAR_EOF > 'mgetstr.c'
- extern char *__modemcap;
-
- char *mgetstr (id, area)
- register char *id;
- register char **area;
- {
- register char *cp = __modemcap;
- register char *str = *area; /* start of current string */
-
- if (__modemcap == (char *) 0) /* has mgetent() been called? ... */
- return ((char *) 0); /* ... no, can't find string */
-
- while (*cp != ':' && *cp != 0) /* find first entry in cap */
- cp++;
-
- if (*cp == 0) /* empty entry??? */
- return ((char *) 0); /* ... yes, bad modemcap entry */
- else
- cp++; /* point to first character in next */
-
- while (*cp != 0) { /* until entry found or end of entry */
- if (cp[0] == id[0] && cp[1] == id[1]) { /* found entry!!! */
- if (cp[2] != '=') /* is it a string value??? */
- return ((char *) 0); /* no, something else */
- else
- break; /* yes, entry was found */
- } else { /* not entry, skip this entire entry */
- while (*cp != ':' && *cp != 0)
- cp++; /* search for end of current entry */
-
- if (*cp != 0)
- cp++; /* skip terminating character */
- }
- }
- if (*cp == 0) /* end of modem cap entry */
- return ((char *) 0);
-
- cp += 3; /* point to actual string */
- while (*cp != ':' && *cp != 0) { /* for every character in string ... */
- if (*cp == '\\') { /* translate escaped character */
- cp++;
- switch (*cp) {
- case 'n': /* newline */
- **area = '\n';
- (*area)++;
- cp++;
- break;
- case 'r': /* carriage return */
- **area = '\r';
- (*area)++;
- cp++;
- break;
- case 'b': /* backspace */
- **area = '\b';
- (*area)++;
- cp++;
- break;
- case 'f': /* form feed */
- **area = '\f';
- (*area)++;
- cp++;
- break;
- case 't': /* tab */
- **area = '\t';
- (*area)++;
- cp++;
- break;
- case 'E': /* Escape character */
- **area = 033;
- (*area)++;
- cp++;
- break;
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- **area = ((cp[0] - '0') << 6) +
- ((cp[1] - '0') << 3) +
- (cp[2] - '0');
- (*area)++;
- cp += 3;
- break;
- default:
- **area = *cp++;
- (*area)++;
- break;
- }
- } else if (*cp == '^') { /* some control character */
- cp++;
- if (*cp >= '@' && *cp <= '_') {
- **area = *cp - '@';
- (*area)++;
- }
- cp++;
- } else { /* some normal character */
- **area = *cp++; /* put character in area */
- (*area)++;
- }
- }
- *((*area)++) = 0; /* null terminate area and string */
- return (str); /* return pointer to start of string */
- }
- SHAR_EOF
- fi
- if test -f 'mgetflag.c'
- then
- echo shar: "will not over-write existing file 'mgetflag.c'"
- else
- cat << \SHAR_EOF > 'mgetflag.c'
- extern char *__modemcap;
-
- mgetflag (id)
- register char *id;
- {
- register char *cp = __modemcap;
-
- if (__modemcap == (char *) 0) /* has mgetent() been called? ... */
- return (-1); /* ... no, can't find number */
-
- while (*cp != ':' && *cp != 0) /* find first entry in cap */
- cp++;
-
- if (*cp == 0) /* empty entry??? */
- return (0); /* ... yes, bad modemcap entry */
- else
- cp++; /* point to first character in next */
-
- while (*cp != 0) { /* until entry found or end of entry */
- if (cp[0] == id[0] && cp[1] == id[1]) /* found entry!!! */
- return (1); /* return true */
- else { /* not entry, skip this entire entry */
- while (*cp != ':' && *cp != 0)
- cp++; /* search for end of current entry */
-
- if (*cp != 0)
- cp++; /* skip terminating character */
- }
- }
- return (0);
- }
- SHAR_EOF
- fi
- if test -f 'mgetnum.c'
- then
- echo shar: "will not over-write existing file 'mgetnum.c'"
- else
- cat << \SHAR_EOF > 'mgetnum.c'
- extern char *__modemcap;
-
- mgetnum (id)
- register char *id;
- {
- register char *cp = __modemcap;
-
- if (__modemcap == (char *) 0) /* has mgetent() been called? ... */
- return (-1); /* ... no, can't find number */
-
- while (*cp != ':' && *cp != 0) /* find first entry in cap */
- cp++;
-
- if (*cp == 0) /* empty entry??? */
- return (-1); /* ... yes, bad modemcap entry */
- else
- cp++; /* point to first character in next */
-
- while (*cp != 0) { /* until entry found or end of entry */
- if (cp[0] == id[0] && cp[1] == id[1]) { /* found entry!!! */
- if (cp[2] != '#') /* is it a numeric value??? */
- return (-1); /* no, something else */
-
- return (atoi (&cp[3])); /* return value (just after #) */
- } else { /* not entry, skip this entire entry */
- while (*cp != ':' && *cp != 0)
- cp++; /* search for end of current entry */
-
- if (*cp != 0)
- cp++; /* skip terminating character */
- }
- }
- return (-1);
- }
- SHAR_EOF
- fi
- if test -f 'mdial.c'
- then
- echo shar: "will not over-write existing file 'mdial.c'"
- else
- cat << \SHAR_EOF > 'mdial.c'
- #include "modemcap.h"
- #include <setjmp.h>
- #include <signal.h>
- #include <dial.h>
-
- static jmp_buf env; /* long jump buffer if timeout in read */
- extern int merrno;
-
- static timeout ()
- {
- longjmp (env, 1);
- }
-
- mdial (telno, fd)
- char *telno;
- int fd;
- {
- char buf[64]; /* telephone buffer if AS is false */
- char command[80]; /* dial command buffer */
- int i, j; /* index and length of telephone number */
- char c; /* single character for connection verification */
-
- if (! DI)
- return (merrno = A_PROB); /* can't dial phone anyhow */
-
- if (! AS) /* never used any other kind of modem */
- return (merrno = A_PROB);
- else /* normal ascii character phone numbers */
- strcpy (buf, telno);
-
- sprintf (command, "%s%s%s%s%s", CS, DS, buf, DE, CE);
- if (setjmp (env) != 0) {
- signal (SIGALRM, SIG_DFL);
- return (merrno = D_HUNG);
- }
- signal (SIGALRM, timeout);
- alarm (10);
- write (fd, command, strlen (command));
-
- if (CO) { /* verify connection */
- if (setjmp (env) != 0) {
- signal (SIGALRM, SIG_DFL);
- return (merrno = A_PROB);
- }
- signal (SIGALRM, timeout);
- if (TT)
- alarm (30);
- else
- alarm (30 + strlen (telno) / 2);
-
- for (i = 0;CO[i] != 0;) {
- if (read (fd, &c, 1) != 1)
- continue;
-
- if (CO[i] == c)
- i++;
- else
- i = 0;
- }
- return (0);
- }
- return (0);
- }
- SHAR_EOF
- fi
- if test -f 'merror.c'
- then
- echo shar: "will not over-write existing file 'merror.c'"
- else
- cat << \SHAR_EOF > 'merror.c'
- #include <stdio.h>
-
- int merrno;
-
- char *_merr_list[] = {
- "No error",
- "Interrupt occurred",
- "Dialer Hung",
- "No answer",
- "Illegal baud rate",
- "ACU Problem",
- "Line Problem",
- "Can't open LDEVS file",
- "Requested device not available",
- "Requested device not known",
- "No device available at requested baud",
- "No device known at requested baud"
- };
-
- int _msys_nerr = (sizeof (_merr_list) / sizeof (char *));
-
- merror (s)
- char *s;
- {
- int i = - merrno;
-
- if (0 <= i && i < _msys_nerr)
- fprintf (stderr, "%s: %s\n", s, _merr_list[i]);
- else
- fprintf (stderr, "%s: Error %d\n", s, merrno);
- }
- SHAR_EOF
- fi
- if test -f 'initmodem.c'
- then
- echo shar: "will not over-write existing file 'initmodem.c'"
- else
- cat << \SHAR_EOF > 'initmodem.c'
- #include "modemcap.h"
-
- static char f_names[] = "asditthc";
- static char *f_caps[] = {
- &AS, &DI, &TT, &HC
- };
-
- static char i_names[] = "bdblidad";
- static int *i_caps[] = {
- &BD, &BL, &ID, &AD
- };
-
- static char c_names[] = "cscedsdeiscoclathu";
- static char **c_caps[] = {
- &CS, &CE, &DS, &DE, &IS, &CO, &CL, &AT, &HU
- };
-
- initmodem (modem, fd)
- char *modem; /* name of modem */
- int fd; /* channel to modem */
- {
- static char mcapbuf[1024];
- static char area[1024];
- char *ap = area;
- register char *cp;
- register int i, j;
- register char *s;
- char *mgetstr ();
-
- if (mgetent (mcapbuf, modem) != 1)
- return (0);
-
- for (i = 0, cp = f_names;*cp;i++, cp += 2)
- *(f_caps[i]) = mgetflag (cp);
-
- for (i = 0, cp = i_names;*cp;i++, cp += 2) {
- j = mgetnum (cp);
- if (j >= 0)
- *(i_caps[i]) = j;
- else
- *(i_caps[i]) = 0;
- }
- for (i = 0, cp = c_names;*cp;i++, cp += 2)
- *(c_caps[i]) = mgetstr (cp, &ap);
-
- if (IS != (char *) 0) {
- write (fd, IS, strlen (IS));
- if (ID)
- sleep (ID);
- }
- return (1);
- }
- SHAR_EOF
- fi
- if test -f 'hangup.c'
- then
- echo shar: "will not over-write existing file 'hangup.c'"
- else
- cat << \SHAR_EOF > 'hangup.c'
- #include "modemcap.h"
- #ifdef UNIX_S5
- #include <termio.h>
- #endif
- #ifdef UNIX_V7
- #include <sgtty.h>
- #endif
-
- extern int merrno;
-
- hangup (fd)
- int fd;
- {
- #ifdef UNIX_S5
- struct termio termio;
- struct termio hupcl;
- #endif
- #ifdef UNIX_V7
- struct sgttyb termio;
- struct sgttyb hupcl;
- #endif
- if (HU == (char *) 0 && HC == 0) {
- undial (fd);
- return (0);
- }
- if (AT != (char *) 0) {
- write (fd, AT, strlen (AT));
- if (AD)
- sleep (AD);
- }
- if (HU) {
- if (CS)
- write (fd, CS, strlen (CS));
- write (fd, HU, strlen (HU));
- if (CE)
- write (fd, CE, strlen (CE));
-
- if (IS) {
- write (fd, IS, strlen (IS));
- if (ID)
- sleep (ID);
- }
- undial (fd);
- return (1);
- }
- #ifdef UNIX_S5
- ioctl (fd, TCGETA, &termio);
- ioctl (fd, TCGETA, &hupcl);
-
- hupcl.c_cflag &= ~CBAUD;
- hupcl.c_cflag |= HUPCL;
-
- ioctl (fd, TCSETA, &hupcl);
- sleep (2);
- ioctl (fd, TCSETA, &termio);
- #endif
- #ifdef UNIX_V7
- gtty (fd, &termio);
- gtty (fd, &hupcl);
-
- hupcl.sg_ispeed = B0;
- hupcl.sg_ospeed = B0;
- stty (fd, &hupcl);
- sleep (2);
- stty (fd, &termio);
- #endif
- undial (fd);
- return (1);
- }
- SHAR_EOF
- fi
- if test -f 'dial.c'
- then
- echo shar: "will not over-write existing file 'dial.c'"
- else
- cat << \SHAR_EOF > 'dial.c'
- #include <fcntl.h>
- #include <dial.h>
- #include <signal.h>
- #include <stdio.h>
- #include "modemcap.h"
-
- #ifdef UNIX_V7
- typedef int void;
- #endif
- static char lockfile[64];
- static int modemfd = -1;
- extern int merrno;
-
- static findline (line, baud)
- char *line;
- int baud;
- {
- int exists = 0;
- int l_baud;
- char l_line[DVC_LEN+1];
- char l_type[DVC_LEN+1];
- char buf[64];
- FILE *fp;
-
- if ((fp = fopen (LDEVS, "r")) == NULL)
- return (merrno = NO_Ldv);
-
- while (fgets (buf, 64, fp) != NULL) {
- if (buf[0] == '#') /* ignore comment lines */
- continue;
-
- if (sscanf (buf, "%s%s%*s%d", l_type, l_line, &l_baud) != 3)
- continue; /* mangled line */
-
- if (strcmp (l_type, "DIR") != 0)
- continue; /* not a direct connect line */
-
- if (strcmp (l_line, line) == 0)
- exists++; /* say device exists at some baud rate */
- else
- continue; /* wrong device */
-
- if (l_baud == baud) { /* found device at desired baud rate */
- fclose (fp);
- return (1);
- }
- }
- if (exists)
- return (merrno = ILL_BD);
- else
- return (merrno = DV_NT_K);
- }
-
- static char *findmodem (line)
- {
- static char modemtype[16];
- char device[DVC_LEN + 1];
- char buf[82];
- FILE *fp;
-
- if ((fp = fopen (_MODEMTYPE_, "r")) == NULL)
- return (NULL);
-
- while (fgets (buf, 82, fp) != NULL) {
- if (buf[0] == '#')
- continue;
-
- sscanf (buf, "%s%s\n", modemtype, device);
- if (strcmp (line, device) == 0) {
- fclose (fp);
- return (modemtype);
- }
- }
- fclose (fp);
- return (NULL);
- }
-
- struct speedlist {
- int value;
- int name;
- } speeds[] = {
- { 0, 0},
- { 110, B110},
- { 300, B300},
- { 600, B600},
- { 1200, B1200},
- { 2400, B2400},
- { 4800, B4800},
- { 9600, B9600},
- {19200, EXTA},
- {38400, EXTB},
- { -1, -1}
- };
-
- static findspeed (speed)
- int speed;
- {
- register struct speedlist *ps;
-
- for (ps = speeds; ps->value >= 0; ps++)
- if (ps->value == speed)
- return (ps->name);
-
- return (0);
- }
-
- alarmcatch ()
- {
- long timebuf[2];
-
- time (&timebuf[0]);
- timebuf[1] = timebuf[0];
-
- utime (lockfile, timebuf);
- signal (SIGALRM, alarmcatch);
- alarm (3600);
- }
-
- hupcatch ()
- {
- close (modemfd);
- unlink (lockfile);
- signal (SIGHUP, SIG_DFL);
- }
-
- int dial (call)
- CALL *call;
- {
- char modemline[64]; /* device name */
- char *modemname; /* modemcap name of modem */
- char *strcpy (),
- *strcat ();
- #ifdef UNIX_S5
- struct termio termio;
- #endif
- #ifdef UNIX_V7
- struct sgttyb termio;
- #endif
- int fd;
- int err;
-
- strcat (strcpy (modemline, DEVDIR), call->line);
- strcat (strcpy (lockfile, LOCK), call->line);
-
- /*
- * FIX - Version 7 does not have three operand open(), write
- * conditional compilation for this here ...
- */
-
- if (access (lockfile, 0) == 0 || (fd = creat (lockfile, 0)) == -1)
- return (merrno = DV_NT_A); /* lock existed or couldn't be created */
- else
- close (fd); /* created lock, now close descriptor */
-
- fd = -1; /* channel illegal until line is opened */
-
- if ((err = findline (call->line, call->baud)) <= 0)
- goto error;
-
- if ((modemname = findmodem (call->line)) == NULL) { /* can't determine the type of modem */
- err = DV_NT_K;
- goto error;
- }
- if ((fd = open (modemline, O_RDWR)) < 0) { /* can't open modem line */
- err = L_PROB;
- goto error;
- }
- #ifdef UNIX_S5
- if (call->attr != (struct termio *) 0) { /* set attributes */
- if (ioctl (fd, TCSETA, call->attr) == -1) { /* some ioctl() problem */
- err = L_PROB;
- goto error;
- }
- } else {
- ioctl (fd, TCGETA, &termio);
- if ((termio.c_cflag = findspeed (call->baud)) == 0) {
- err = ILL_BD;
- goto error;
- }
- termio.c_cflag |= (CS8|CREAD|HUPCL);
- termio.c_iflag = 0;
- termio.c_oflag = 0;
- termio.c_lflag = 0;
- termio.c_cc[VMIN] = 1;
- termio.c_cc[VTIME] = 1;
- if (ioctl (fd, TCSETA, &termio) == -1) {
- err = L_PROB;
- goto error;
- }
- }
- #endif
- #ifdef UNIX_V7
- if (call->attr != (struct sgttyb *) 0) { /* set attributes */
- if (gtty (fd, call->attr) == -1) { /* some gtty() problem */
- err = L_PROB;
- goto error;
- }
- } else {
- gtty (fd, &termio);
- if ((termio.sg_ispeed = findspeed (call->baud)) == 0) {
- err = ILL_BD;
- goto error;
- }
- termio.sg_ospeed = termio.sg_ispeed;
- termio.sg_flags = RAW|ANYP;
- termio.sg_erase = -1;
- termio.sg_kill = -1;
- if (stty (fd, &termio) == -1) {
- err = L_PROB;
- goto error;
- }
- }
- #endif
- initmodem (modemname, fd); /* setup modemcap variables */
- if (call->telno == (char *) 0) /* no phone number, connection complete */
- goto okay;
-
- if (! DI) { /* modem has no ACU!!! */
- err = A_PROB; /* no ACU to attach to */
- goto error;
- }
- if (BD != call->baud) { /* is connection desired at high speed? */
- if (BL != call->baud) { /* is connection desired at low speed? */
- err = ILL_BD; /* modem can't handle this speed */
- goto error;
- }
- BD = BL; /* set baud to low baud rate */
- CO = CL; /* set connect reply to low baud reply */
- }
- if (err = mdial (call->telno, fd)) /* some error trying to dial */
- goto error;
-
- signal (SIGALRM, alarmcatch); /* set catcher for ALARM clock */
- signal (SIGHUP, hupcatch); /* set catcher for HANG UP */
- alarm (3600); /* set clock for 1 hour to touch lock */
-
- okay:
- return (modemfd = fd);
-
- error:
- unlink (lockfile);
- if (fd > 2)
- close (fd);
- return (merrno = err);
- }
-
- void undial (fd)
- int fd;
- {
- if (fd > 2)
- close (fd);
-
- unlink (lockfile);
- alarm (0);
- }
- SHAR_EOF
- fi
- if test -f 'call.c'
- then
- echo shar: "will not over-write existing file 'call.c'"
- else
- cat << \SHAR_EOF > 'call.c'
- #include <dial.h>
- #include <stdio.h>
-
- CALL call;
-
- main (argc, argv)
- int argc;
- char **argv;
- {
- if (strcmp (argv[0], "call") == 0)
- exit (do_call (argc, argv));
- else if (strcmp (argv[0], "hangup") == 0)
- exit (do_hup (argv, argv));
-
- fprintf (stderr, "usage: call tty baud telno\n");
- fprintf (stderr, " hangup tty baud\n");
- exit (1);
- }
-
- do_call (argc, argv)
- int argc;
- char **argv;
- {
- int fd;
-
- if (argc < 4) {
- fprintf (stderr, "usage: call tty baud telno\n");
- exit (1);
- }
- call.line = argv[1];
- call.baud = atoi (argv[2]);
- call.telno = argv[3];
-
- fd = dial (&call);
- if (fd < 0) {
- merror (argv[0]);
- exit (2);
- }
- undial (fd);
- return (0);
- }
-
- do_hup (argc, argv)
- int argc;
- char **argv;
- {
- int fd;
-
- if (argc < 3) {
- fprintf (stderr, "usage: hangup tty baud\n");
- exit (1);
- }
- call.line = argv[1];
- call.baud = atoi (argv[2]);
-
- fd = dial (&call);
- if (fd < 0) {
- merror (argv[0]);
- exit (2);
- }
- hangup (fd);
- undial (fd);
- return (0);
- }
- SHAR_EOF
- fi
- exit 0
- # End of shell archive
- --
- John F. Haugh II HECI Exploration Co. Inc.
- UUCP: ...!ihnp4!killer!jfh 11910 Greenville Ave, Suite 600
- "Don't Have an Oil Well?" Dallas, TX. 75243
- " ... Then Buy One!" (214) 231-0993
-